package com.zone.vehicle.superapp.view.home.pay;

import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.ViewModelProvider;

import com.saicmotor.pay.PayManager;
import com.saicmotor.pay.db.PayDaoUtilsStore;
import com.saicmotor.pay.db.entity.Pay;
import com.saicmotor.pay.entity.OrderEntity;
import com.saicmotor.pay.http.Entity.QueryTranStatusEntity;
import com.saicmotor.pay.http.ResultCallback;
import com.saicmotor.pay.util.DateUtils;
import com.saicmotor.pay.util.EncodingUtils;
import com.saicmotor.pay.util.PayUtils;
import com.zone.lib.download.db.entity.Download;
import com.zone.lib.download.enums.AppStatusEnum;
import com.zone.lib.download.utils.DownloadUtil;
import com.zone.lib.download.utils.SharedPreferencesUtil;
import com.zone.sdk.module.appstore.entity.AppDetailEntity;
import com.zone.vehicle.superapp.R;
import com.zone.vehicle.superapp.bean.AppBean;
import com.zone.vehicle.superapp.databinding.FragmentOrderPayBinding;
import com.zone.vehicle.superapp.model.HomeViewModel;
import com.zone.vehicle.superapp.model.ViewModelFactory;
import com.zone.vehicle.superapp.view.common.base.BaseFragment;

import org.apache.commons.lang3.ObjectUtils;

import java.util.Timer;
import java.util.TimerTask;

import static com.zone.vehicle.superapp.view.home.HomeFragment.APP_DETAIL_FRAGMENT;

public class OrderPayFragment extends BaseFragment {
    private static final String TAG = "OrderPayFragment";
    private FragmentOrderPayBinding binding;

    private static final long TIME_MAX = 1000 * 60 * 30;
    private static final long TIME_STEP = 1000 * 5;
    private static final long TRY_COUNT = TIME_MAX / TIME_STEP;

    private HomeViewModel viewModel;
    private Activity activity;
    private long retryCount = TRY_COUNT;
    private Timer timer = null;
    private TimerTask task = new QueryTask();

    private ResultCallback<QueryTranStatusEntity> mCallback = new ResultCallback<QueryTranStatusEntity>() {
        @Override
        public void onSuccess(QueryTranStatusEntity queryTranStatusEntity) {
            String st = queryTranStatusEntity.getPayStatus();
            if (ObjectUtils.isEmpty(st)) {
                Log.w(TAG, "fail query status, status null " + st);
                return;
            }
            int status = Integer.parseInt(st);
            if (status == PayUtils.PAY_ST_SUCCESS) {
                savePayDB(queryTranStatusEntity);
                queryFinish(true);
                viewModel.setPayStatus(true);
            } else if (status == PayUtils.PAY_ST_FAILED) {
                queryFinish(false);
            }
        }

        @Override
        public void onError(String errorCode, String message) {
            Log.w(TAG, "error query pay of error " + errorCode + "  " + message);
        }
    };

    private Runnable mListenRunnable = new Runnable() {
        @Override
        public void run() {
            if (timer == null){
                return;
            }
            Object o = viewModel.getOrderEntity().getValue();
            if (ObjectUtils.isEmpty(o)) {
                Log.w(TAG, "error query pay of null order entity");
                return;
            }
            OrderEntity orderEntity = (OrderEntity) o;
            PayManager.getInstance().queryTranStatus(
                    orderEntity.getMerchOrderId(),
                    orderEntity.getPlatformMerchId(),
                    orderEntity.getTransNo(),
                    mCallback
            );
        }
    };

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        activity = getActivity();
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        binding = FragmentOrderPayBinding.inflate(inflater);
        viewModel = new ViewModelProvider(requireActivity(), new ViewModelFactory()).get(HomeViewModel.class);
        initView();
//        initListen();
        return binding.getRoot();
    }

    @Override
    public void onResume() {
        super.onResume();
        if (updateView()) {
            initListen();
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        releaseTimer();
    }

    @Override
    public void onStop() {
        super.onStop();
    }

    private void initView() {
        binding.payBtnBack.setOnClickListener(v -> {
            Log.d(TAG, "btnBack onClick");
            onBack();
        });
        binding.layoutPayResult.setVisibility(View.GONE);
        binding.btnPayResult.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                popPage(APP_DETAIL_FRAGMENT);
            }
        });
        Object obj = viewModel.getCurrentOrderAppEntity();
        if (ObjectUtils.isEmpty(obj)) {
            Log.w(TAG, "init price fail, null order app");
            return;
        }
        AppDetailEntity appEntity = (AppDetailEntity) obj;
        binding.textOrderPayPrice.setText(appEntity.getProductPrice());

        if (updateView()) {
            initListen();
        }
    }

    private boolean updateView() {
        binding.layoutPayCode.setVisibility(View.VISIBLE);
        Object o = viewModel.getPayStringInfo();
        if (ObjectUtils.isEmpty(o)) {
            return false;
        }
        String code = (String) o;
        Bitmap bmp = EncodingUtils.createQRCode(code, 400, 400, 0);
        binding.imageOrderPay.setImageBitmap(bmp);
        return true;
    }

    private void initListen() {
        if (null == task){
            task = new QueryTask();
        }
        if (null == timer) {
            timer = new Timer();
            timer.schedule(task, TIME_STEP, TIME_STEP);
        }
    }

    private void savePayDB(QueryTranStatusEntity entity){
        AppBean appBean = (AppBean) viewModel.getCurrentApp().getValue();
        OrderEntity orderEntity = (OrderEntity) viewModel.getOrderEntity().getValue();
        Pay pay = new Pay();
        pay.setAppCode(appBean.getCode());
        pay.setAttach(entity.getAttach());
        pay.setCreateTime(DateUtils.getStringDate());
        pay.setMerchOrderId(entity.getMerchOrderId());
        pay.setOrderAmt(entity.getOrderAmt());
        pay.setPayerBank(entity.getPayerBank());
        pay.setPayerOpenid(entity.getPayerOpenid());
        pay.setPayStatus(entity.getPayStatus());
        pay.setPayStatusDesc(entity.getPayStatusDesc());
        pay.setPlatformMerchId(entity.getPlatformMerchId());
        pay.setProductBrand(entity.getProductBrand());
        pay.setProductBrandDesc(entity.getProductBrandDesc());
        pay.setRealPayedAmt(entity.getRealPayedAmt());
        pay.setTransAmt(entity.getTransAmt());
        pay.setTransId(entity.getTransId());
        pay.setUserId(SharedPreferencesUtil.getInstance(activity).getUserId(activity));
        PayDaoUtilsStore.getInstance().getPayAppDaoUtils().insert(pay);
    }

    private void queryFinish(boolean success) {
        releaseTimer();
        AppStatusEnum statusEnum;
        if (success) {
            statusEnum = AppStatusEnum.DOWNLOAD_PAYED;
        } else {
            statusEnum = AppStatusEnum.DOWNLOAD_NEED_PAY;
        }
        Object o = viewModel.getCurrentApp().getValue();
        if (ObjectUtils.isEmpty(o)) {
            Log.e(TAG, "error query result of null current app");
            return;
        }

        AppBean appBean = (AppBean) o;
        Download download = appBean.getDownload();
        if (ObjectUtils.isNotEmpty(download)) {
            download.setDownloadStatus(statusEnum.CODE);
        } else {
            download = DownloadUtil.build(statusEnum.CODE, appBean, null);
            appBean.setDownload(download);
        }

        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                binding.layoutPayCode.setVisibility(View.GONE);
                binding.layoutPayResult.setVisibility(View.VISIBLE);
                if (success) {
                    binding.imagePayResult.setImageResource(R.drawable.pay_success);
                    binding.btnBackTxt.setText("订单支付成功");
                    binding.btnPayResult.setText("支付完成");
                } else {
                    binding.imagePayResult.setImageResource(R.drawable.pay_failed);
                    binding.btnBackTxt.setText("订单支付失败");
                }
            }
        });
    }

    private void releaseTimer() {
        if (null != task) {
            task.cancel();
            task = null;
        }
        if (null != timer) {
            timer = null;
        }
    }

    private class QueryTask extends TimerTask{
        @Override
        public void run() {
            retryCount--;
            if (retryCount == 0) {
                Log.e(TAG, "query tome out");
                queryFinish(false);
                return;
            }
            mListenRunnable.run();
        }
    }
}
